package ranab.server.ftp.gui;

import java.io.File;
import java.awt.Color;
import java.awt.Insets;
import java.text.SimpleDateFormat;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTextField;

import ranab.server.ftp.FtpUser;
import ranab.server.ftp.FtpConfig;
import ranab.server.ftp.FtpStatistics;
import ranab.server.ftp.FtpFileListener;
import ranab.server.ftp.FtpStatisticsListener;

/**
 * Ftp server global statistics panel.
 * 
 * @author <a href="mailto:rana_b@yahoo.com">Rana Bhattacharyya</a>
 */
public
class FtpStatisticsPanel extends PluginPanel 
                         implements FtpStatisticsListener, FtpFileListener {                    

    private final static SimpleDateFormat DATE_FMT = new SimpleDateFormat("dd,MMM,yyyy HH:mm");
    
    private FtpConfig mConfig;                   
    private FtpStatistics mStat;
                
    private JTextField mjStartTimeTxt;
    
    private JTextField mjUploadNbrTxt;
    private JTextField mjDownloadNbrTxt;
    private JTextField mjDeleteNbrTxt;
    
    private JTextField mjUploadBytesTxt;
    private JTextField mjDownloadBytesTxt;
    
    private JTextField mjLoginNbrTxt;
    private JTextField mjAnonLoginNbrTxt;
    private JTextField mjConNbrTxt;
    
    private JTextField mjTotalLoginNbrTxt;
    private JTextField mjTotalAnonLoginNbrTxt;
    private JTextField mjTotalConNbrTxt;
    
    private FtpFileTableModel mUploadModel;
    private FtpFileTableModel mDownloadModel;
    private FtpFileTableModel mDeleteModel;
    
    /** 
     * Creates new panel to display ftp global statistics. 
     */
    public FtpStatisticsPanel(FtpTree tree) {
        super(tree);
        initComponents();
        mUploadModel = new FtpFileTableModel();
        mDownloadModel = new FtpFileTableModel();
        mDeleteModel = new FtpFileTableModel();
    }

    /** 
     * This method is called from within the constructor to
     * initialize the panel.
     */
    private void initComponents() {
          
        GridBagConstraints gc;
        setLayout(new GridBagLayout());
        
        // start time
        JLabel jStartTimeLab = new JLabel("Start Time");
        jStartTimeLab.setHorizontalAlignment(JLabel.RIGHT);
        jStartTimeLab.setForeground(Color.black);
        gc = new GridBagConstraints();
        gc.gridx = 0;
        gc.gridy = 0;
        gc.gridwidth = 1;
        gc.anchor = GridBagConstraints.EAST;
        gc.insets = new Insets(15, 0, 0, 5);
        add(jStartTimeLab, gc);
         
        mjStartTimeTxt = new JTextField();
        mjStartTimeTxt.setColumns(15);
        mjStartTimeTxt.setEditable(false);
        gc = new GridBagConstraints();
        gc.gridx = 1;
        gc.gridy = 0;
        gc.gridwidth = 2;
        gc.anchor = GridBagConstraints.WEST;
        gc.insets = new Insets(15, 0, 0, 5);
        add(mjStartTimeTxt, gc);
        
        // number of uploads
        JLabel jUploadNbrLab = new JLabel("Number of uploads");
        jUploadNbrLab.setHorizontalAlignment(JLabel.RIGHT);
        jUploadNbrLab.setForeground(Color.black);
        gc = new GridBagConstraints();
        gc.gridx = 0;
        gc.gridy = 1;
        gc.gridwidth = 1;
        gc.anchor = GridBagConstraints.EAST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(jUploadNbrLab, gc);        
        
        mjUploadNbrTxt = new JTextField();
        mjUploadNbrTxt.setColumns(6);
        mjUploadNbrTxt.setEditable(false);
        gc = new GridBagConstraints();
        gc.gridx = 1;
        gc.gridy = 1;
        gc.gridwidth = 2;
        gc.anchor = GridBagConstraints.WEST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(mjUploadNbrTxt, gc);
        
        // number of downloads
        JLabel jDownloadNbrLab = new JLabel("Number of downloads");
        jDownloadNbrLab.setHorizontalAlignment(JLabel.RIGHT);
        jDownloadNbrLab.setForeground(Color.black);
        gc = new GridBagConstraints();
        gc.gridx = 0;
        gc.gridy = 2;
        gc.gridwidth = 1;
        gc.anchor = GridBagConstraints.EAST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(jDownloadNbrLab, gc);
        
        mjDownloadNbrTxt = new JTextField();
        mjDownloadNbrTxt.setColumns(6);
        mjDownloadNbrTxt.setEditable(false);
        gc = new GridBagConstraints();
        gc.gridx = 1;
        gc.gridy = 2;
        gc.gridwidth = 2;
        gc.anchor = GridBagConstraints.WEST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(mjDownloadNbrTxt, gc);
        
        // number of downloads
        JLabel jDeleteNbrLab = new JLabel("Number of deletes");
        jDeleteNbrLab.setHorizontalAlignment(JLabel.RIGHT);
        jDeleteNbrLab.setForeground(Color.black);
        gc = new GridBagConstraints();
        gc.gridx = 0;
        gc.gridy = 3;
        gc.gridwidth = 1;
        gc.anchor = GridBagConstraints.EAST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(jDeleteNbrLab, gc);
        
        mjDeleteNbrTxt = new JTextField();
        mjDeleteNbrTxt.setColumns(6);
        mjDeleteNbrTxt.setEditable(false);
        gc = new GridBagConstraints();
        gc.gridx = 1;
        gc.gridy = 3;
        gc.gridwidth = 2;
        gc.anchor = GridBagConstraints.WEST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(mjDeleteNbrTxt, gc);        
        
        // number of uploaded bytes
        JLabel jUploadBytesLab = new JLabel("Uploaded bytes");
        jUploadBytesLab.setHorizontalAlignment(JLabel.RIGHT);
        jUploadBytesLab.setForeground(Color.black);
        gc = new GridBagConstraints();
        gc.gridx = 0;
        gc.gridy = 4;
        gc.gridwidth = 1;
        gc.anchor = GridBagConstraints.EAST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(jUploadBytesLab, gc);
        
        mjUploadBytesTxt = new JTextField();
        mjUploadBytesTxt.setColumns(15);
        mjUploadBytesTxt.setEditable(false);
        gc = new GridBagConstraints();
        gc.gridx = 1;
        gc.gridy = 4;
        gc.gridwidth = 2;
        gc.anchor = GridBagConstraints.WEST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(mjUploadBytesTxt, gc);
        
        // number of uploaded bytes
        JLabel jDownloadBytesLab = new JLabel("Downloaded bytes");
        jDownloadBytesLab.setHorizontalAlignment(JLabel.RIGHT);
        jDownloadBytesLab.setForeground(Color.black);
        gc = new GridBagConstraints();
        gc.gridx = 0;
        gc.gridy = 5;
        gc.gridwidth = 1;
        gc.anchor = GridBagConstraints.EAST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(jDownloadBytesLab, gc);
        
        mjDownloadBytesTxt = new JTextField();
        mjDownloadBytesTxt.setColumns(15);
        mjDownloadBytesTxt.setEditable(false); 
        gc = new GridBagConstraints();
        gc.gridx = 1;
        gc.gridy = 5;
        gc.gridwidth = 2;
        gc.anchor = GridBagConstraints.WEST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(mjDownloadBytesTxt, gc);
        
        // number of current logins
        JLabel jLoginNbrLab = new JLabel("Current logins");
        jLoginNbrLab.setHorizontalAlignment(JLabel.RIGHT);
        jLoginNbrLab.setForeground(Color.black);
        gc = new GridBagConstraints();
        gc.gridx = 0;
        gc.gridy = 6;
        gc.gridwidth = 1;
        gc.anchor = GridBagConstraints.EAST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(jLoginNbrLab, gc);
        
        mjLoginNbrTxt = new JTextField();
        mjLoginNbrTxt.setColumns(6);
        mjLoginNbrTxt.setEditable(false);
        gc = new GridBagConstraints();
        gc.gridx = 1;
        gc.gridy = 6;
        gc.gridwidth = 2;
        gc.anchor = GridBagConstraints.WEST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(mjLoginNbrTxt, gc);
        
        // number of total logins
        JLabel jTotalLoginNbrLab = new JLabel("Total logins");
        jTotalLoginNbrLab.setHorizontalAlignment(JLabel.RIGHT);
        jTotalLoginNbrLab.setForeground(Color.black);
        gc = new GridBagConstraints();
        gc.gridx = 0;
        gc.gridy = 7;
        gc.gridwidth = 1;
        gc.anchor = GridBagConstraints.EAST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(jTotalLoginNbrLab, gc);
        
        mjTotalLoginNbrTxt = new JTextField();
        mjTotalLoginNbrTxt.setColumns(6);
        mjTotalLoginNbrTxt.setEditable(false);
        gc = new GridBagConstraints();
        gc.gridx = 1;
        gc.gridy = 7;
        gc.gridwidth = 2;
        gc.anchor = GridBagConstraints.WEST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(mjTotalLoginNbrTxt, gc);
        
        // number of current anonymous logins
        JLabel jAnonLoginNbrLab = new JLabel("Current anonymous logins");
        jAnonLoginNbrLab.setHorizontalAlignment(JLabel.RIGHT);
        jAnonLoginNbrLab.setForeground(Color.black);
        gc = new GridBagConstraints();
        gc.gridx = 0;
        gc.gridy = 8;
        gc.gridwidth = 1;
        gc.anchor = GridBagConstraints.EAST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(jAnonLoginNbrLab, gc);
        
        mjAnonLoginNbrTxt = new JTextField();
        mjAnonLoginNbrTxt.setColumns(6);
        mjAnonLoginNbrTxt.setEditable(false);
        gc = new GridBagConstraints();
        gc.gridx = 1;
        gc.gridy = 8;
        gc.gridwidth = 2;
        gc.anchor = GridBagConstraints.WEST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(mjAnonLoginNbrTxt, gc);  
        
        // number of total anonymous logins
        JLabel jTotalAnonLoginNbrLab = new JLabel("Total anonymous logins");
        jTotalAnonLoginNbrLab.setHorizontalAlignment(JLabel.RIGHT);
        jTotalAnonLoginNbrLab.setForeground(Color.black);
        gc = new GridBagConstraints();
        gc.gridx = 0;
        gc.gridy = 9;
        gc.gridwidth = 1;
        gc.anchor = GridBagConstraints.EAST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(jTotalAnonLoginNbrLab, gc);
        
        mjTotalAnonLoginNbrTxt = new JTextField();
        mjTotalAnonLoginNbrTxt.setColumns(6);
        mjTotalAnonLoginNbrTxt.setEditable(false);
        gc = new GridBagConstraints();
        gc.gridx = 1;
        gc.gridy = 9;
        gc.gridwidth = 2;
        gc.anchor = GridBagConstraints.WEST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(mjTotalAnonLoginNbrTxt, gc);
        
        // number of current connections
        JLabel jConNbrLab = new JLabel("Current connections");
        jConNbrLab.setHorizontalAlignment(JLabel.RIGHT);
        jConNbrLab.setForeground(Color.black);
        gc = new GridBagConstraints();
        gc.gridx = 0;
        gc.gridy = 10;
        gc.gridwidth = 1;
        gc.anchor = GridBagConstraints.EAST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(jConNbrLab, gc);
        
        mjConNbrTxt = new JTextField();
        mjConNbrTxt.setColumns(6);
        mjConNbrTxt.setEditable(false);
        gc = new GridBagConstraints();
        gc.gridx = 1;
        gc.gridy = 10;
        gc.gridwidth = 2;
        gc.anchor = GridBagConstraints.WEST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(mjConNbrTxt, gc); 
        
        // number of current connections
        JLabel jTotalConNbrLab = new JLabel("Total connections");
        jTotalConNbrLab.setHorizontalAlignment(JLabel.RIGHT);
        jTotalConNbrLab.setForeground(Color.black);
        gc = new GridBagConstraints();
        gc.gridx = 0;
        gc.gridy = 11;
        gc.gridwidth = 1;
        gc.anchor = GridBagConstraints.EAST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(jTotalConNbrLab, gc);
        
        mjTotalConNbrTxt = new JTextField();
        mjTotalConNbrTxt.setColumns(6);
        mjTotalConNbrTxt.setEditable(false);
        gc = new GridBagConstraints();
        gc.gridx = 1;
        gc.gridy = 11;
        gc.gridwidth = 2;
        gc.anchor = GridBagConstraints.WEST;
        gc.insets = new Insets(5, 0, 0, 5);
        add(mjTotalConNbrTxt, gc);
    }
        
    /**
     * Get upload file table model.
     */
    public FtpFileTableModel getUploadModel() {
        return mUploadModel;
    }
    
    /**
     * Get download file table model.
     */
    public FtpFileTableModel getDownloadModel() {
        return mDownloadModel;
    }
    
    /**
     * Get delete file table model.
     */
    public FtpFileTableModel getDeleteModel() {
        return mDeleteModel;
    }
    
    /**
     * Upload notification.
     */
    public void notifyUpload() {
        mjUploadNbrTxt.setText(String.valueOf(mStat.getFileUploadNbr()));
        mjUploadBytesTxt.setText(String.valueOf(mStat.getFileUploadSize()));
    }
    
    /**
     * Download notification.
     */
    public void notifyDownload() {
        mjDownloadNbrTxt.setText(String.valueOf(mStat.getFileDownloadNbr()));
        mjDownloadBytesTxt.setText(String.valueOf(mStat.getFileDownloadSize()));
    }
    
    
    /**
     * Delete notification.
     */
    public void notifyDelete() {
        mjDeleteNbrTxt.setText(String.valueOf(mStat.getFileDeleteNbr()));
    }
    
    /**
     * User login notification.
     */
    public void notifyLogin() {
          mjLoginNbrTxt.setText(String.valueOf(mStat.getLoginNbr()));
          mjAnonLoginNbrTxt.setText(String.valueOf(mStat.getAnonLoginNbr()));
          mjTotalLoginNbrTxt.setText(String.valueOf(mStat.getTotalLoginNbr()));
          mjTotalAnonLoginNbrTxt.setText(String.valueOf(mStat.getTotalAnonLoginNbr()));
    }
    
    /**
     * User logout notification.
     */
    public void notifyLogout() {
        notifyLogin();
    } 
     
    /**
     * Notify open/close connection
     */ 
    public void notifyConnection() {
        mjConNbrTxt.setText(String.valueOf(mStat.getConnectionNbr()));
        mjTotalConNbrTxt.setText(String.valueOf(mStat.getTotalConnectionNbr()));
    } 
     
    /**
     * Notify file upload
     */ 
    public void notifyUpload(final File fl, final FtpUser user) {
        mUploadModel.newEntry(fl.getAbsolutePath(), user);
    } 
    
    /**
     * Notify file download
     */ 
    public void notifyDownload(final File fl, final FtpUser user) {
        mDownloadModel.newEntry(fl.getAbsolutePath(), user);
    }
    
    /**
     * Notify file delete
     */ 
    public void notifyDelete(final File fl, final FtpUser user) {
        mDeleteModel.newEntry(fl.getAbsolutePath(), user);
    }
    
    /**
     * Initialize the statistics data.
     */
    public void refresh(FtpConfig cfg) {
        mConfig = cfg;
        if (cfg != null) {
            mStat = mConfig.getStatistics();
            mStat.setListener(this);
            mStat.setFileListener(this);
            mjStartTimeTxt.setText(DATE_FMT.format(mStat.getStartTime()));
            notifyUpload();
            notifyDownload();
            notifyDelete();
            notifyLogin();
            notifyConnection();
        }
        else {
            mStat = null;
        }
        
        mUploadModel.reset();
        mDownloadModel.reset();
        mDeleteModel.reset();
    }
    
    
    /**
     * Is displayable
     */
    public boolean isDisplayable() {
        return mConfig != null;
    } 
     
}